///<reference path='jquery.d.ts' />
///<reference path='SPRESTSite.ts'/>
///<reference path='SPRESTUtil.ts'/>
///<reference path='SPRESTConstants.ts'/>

// Module
module SPREST {

    // Class
    export class Context  {
        
        // Static
        public static contexts: Context[] = null;

        static GetContext(contextUrl: string): SPREST.Context {
            if (contexts == null) {
                contexts = [];
                var context: Context = new SPREST.Context(contextUrl);
                contexts.push(context);
                return context;
            }

            var contextUrlLower: string = contextUrl.toLowerCase();
            for (var looper = 0; looper < contexts.length; looper++) {
                var curContext: SPREST.Context = contexts[looper];
                if (curContext.ContextUrl.toLowerCase() == contextUrlLower) return curContext;
            }

           var context: Context = new SPREST.Context(contextUrl);
           contexts.push(context);
           return context;

        }
        
        public contextInfoUrl: string = null;
        public serverVersion: number = 0;
        public contextSiteUrl: string = null;
        public contextWebUrl: string = null;
        public RequestDigest: string = null;

        public ready: bool = false;
        public started: bool = false;
        public dfd: JQueryDeferred = $.Deferred();
        // Constructor
        constructor (public ContextUrl:string) { 
            // Find SharePoint
            this.contextInfoUrl = SPREST.Util.concatenateUrl(ContextUrl, SPREST.Constants.ContextInfoUrl);
            this.start();
        }
        
        public siteProp: SPREST.Site = null;
        getSite(): SPREST.Site { 
            if (this.siteProp != null) return this.siteProp;
            this.siteProp = new SPREST.Site(this);
            var dfd:JQueryDeferred = this.siteProp.start();
            return this.siteProp;
        }

        public webProp: SPREST.Web = null;
        getWeb(): SPREST.Web {
            // Note: that here we won't call site.start
            if (this.siteProp == null) this.siteProp = new SPREST.Site(this);
            if (this.webProp != null) return this.webProp; 
            this.webProp = new SPREST.Web(this, this.siteProp, this.contextWebUrl);
            var dfd: JQueryDeferred = this.webProp.start();
            return this.webProp;
        }

        start():JQueryDeferred {
            var myThis: Context = this;
            if (myThis.started) return this.dfd;
            myThis.started = true;
            $.ajaxSetup({ cache: false, crossDomain: true });
            $.support.cors = true;
            $.ajax(this.contextInfoUrl,
                {
                    async: true,
                    headers: { "Accept":"application/json;odata=verbose" },
                    type: "POST",
                }).fail(function(req, status, error) {
                    myThis.dfd.reject(myThis, req, status, error);
                 } ).done(function (data) {
                     myThis.RequestDigest = data.d.GetContextWebInformation.FormDigestValue;
                    myThis.serverVersion = data.d.GetContextWebInformation.LibraryVersion;
                    myThis.contextSiteUrl = data.d.GetContextWebInformation.SiteFullUrl;
                    myThis.contextWebUrl = data.d.GetContextWebInformation.WebFullUrl;
                    // TODO: Supported Schema Versions
                    myThis.ready = true;
                    myThis.dfd.resolve(myThis);
                });
            return myThis.dfd;
        }
    }
}

